package com.info3k.client.commands.location;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.maps.client.MapType;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.control.LargeMapControl3D;
import com.google.gwt.maps.client.control.MapTypeControl;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.info3k.client.Info3K;
import com.info3k.client.commands.address.ShowAddressesCommand;
import com.info3k.client.components.ContentBox;
import com.info3k.client.components.InfoWindow;
import com.info3k.client.components.Rating;
import com.info3k.client.domain.Location;
import com.info3k.client.domain.User;


public class ShowLocationCommand extends ContentBox implements Command {

	private MapWidget map = new MapWidget();
	
	private Rating rating = new Rating(0, 10, Rating.LTR);
	
	private Button editButton = new Button(Info3K.msgs.editLocation());
	
	public ShowLocationCommand(final Location location, final Info3K info3k){
		setText(location.getLocationName());

		User uu = info3k.getLoginManager().getUser();
		if(uu!=null){
			if(uu.getUsername().equals(location.getUser().getUsername())){
				headerRight.add(editButton);
				headerRight.setCellHorizontalAlignment(editButton, HorizontalPanel.ALIGN_RIGHT);
			}
		}
		
		editButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent e) {
				UpdateLocationCommand cmd = new UpdateLocationCommand(info3k, location);
				cmd.execute();
			}
		});

		
		map.setSize("100%", "300px");
		map.addControl(new LargeMapControl3D());
		map.setCurrentMapType(MapType.getSatelliteMap());
		map.addControl(new MapTypeControl());
		
		for (String string : location.getLatLong()) {
			String[] array = string.split("%");
			if(array.length==2){
				Marker marker = new Marker(LatLng.newInstance(Double.parseDouble(array[0]),Double.parseDouble(array[1])));
				map.addOverlay(marker);
				map.setCenter(LatLng.newInstance(marker.getLatLng().getLatitude(), marker.getLatLng().getLongitude()), 14);
			}
		}
			
		HorizontalPanel horPanel = new HorizontalPanel();
		horPanel.setWidth("100%");
		VerticalPanel verPanel1 = new VerticalPanel();
		VerticalPanel verPanel2 = new VerticalPanel();
		
		horPanel.add(verPanel1);
		horPanel.add(verPanel2);
		
		horPanel.setCellWidth(verPanel1, "60%");
		horPanel.setCellWidth(verPanel2, "40%");
		
		horPanel.setCellHorizontalAlignment(verPanel2, HorizontalPanel.ALIGN_RIGHT);
		
		if(location.getRate()==null) location.setRate(0.);
		if(location.getViews()==null) location.setViews(0L);
		if(location.getNumRates()==null) location.setNumRates(0L);
		
		String s3 = Info3K.msgs.views() + ": ";
		s3 += "<b>" + location.getViews() + "</b><br>"; 
		
		s3 += Info3K.msgs.rate() + ": ";
		String rate = location.getRate().toString();
		if(rate.length()>4) rate = rate.substring(0, 4);
		s3 += "<b>" + rate + "</b>";
		
		final HTML htmlViewRate = new HTML();
		htmlViewRate.setHTML(s3);
		
		verPanel2.setCellHorizontalAlignment(rating, HorizontalPanel.ALIGN_RIGHT);
		verPanel2.setCellHorizontalAlignment(htmlViewRate, HorizontalPanel.ALIGN_RIGHT);
		
		content.add(horPanel);
		
		verPanel1.add(new Label(Info3K.msgs.creator() + ": " + location.getUser().getUsername()));
		if(location.getCategory()!=null){
			verPanel1.add(new Label(Info3K.msgs.category() + ": " + location.getCategory().getName()));
		}
		if(location.getFloor()!=null){
			verPanel1.add(new Label(Info3K.msgs.floor() + ": " + location.getFloor()));
		}
		
		rating.setValue(location.getRate().intValue());
		
		verPanel2.add(htmlViewRate);
		verPanel2.add(rating);
		
		HTML lbl = new HTML(Info3K.msgs.locationDescription() + ":");
		content.add(lbl);
		
		content.add(new HTML(location.getDescription()));
		
		if(location.getAddresses()!=null && location.getAddresses().length>0){
			Button showAddressesBtn = new Button(Info3K.msgs.showAddresses());
			showAddressesBtn.addClickHandler(new ClickHandler(){
				public void onClick(ClickEvent event) {
					ShowAddressesCommand showAddressesCommand = new ShowAddressesCommand(location.getAddresses());
					showAddressesCommand.execute();
				}
			});
			
			footer.add(showAddressesBtn);
		}
		content.add(map);
		
		Info3K.infoService.viewLocation(location, new AsyncCallback<Void>(){
			public void onFailure(Throwable caught) {
				InfoWindow.showMessage(Info3K.msgs.error(), caught.getMessage());
			}

			public void onSuccess(Void result) {
				location.setViews(location.getViews() + 1);
				String s3 = Info3K.msgs.views() + ": ";
				s3 += "<b>" + location.getViews() + "</b><br>"; 
				
				s3 += Info3K.msgs.rate() + ": ";
				String rate = location.getRate().toString();
				if(rate.length()>4) rate = rate.substring(0, 4);
				s3 += "<b>" + rate + "</b>";
				
				htmlViewRate.setHTML(s3);
			}
		});
		
		rating.addValueChangeHandler(new ValueChangeHandler<Integer>(){
			public void onValueChange(ValueChangeEvent<Integer> e) {
				Info3K.loader.setVisible(true);
				Info3K.infoService.rateLocation(location, Double.valueOf(e.getValue()), new AsyncCallback<Void>(){
					public void onFailure(Throwable caught) {
						Info3K.loader.setVisible(false);
						InfoWindow.showMessage(Info3K.msgs.error(), caught.getMessage());
					}

					public void onSuccess(Void result) {
						Info3K.loader.setVisible(false);
						InfoWindow.showMessage(Info3K.msgs.ok(), Info3K.msgs.locationRatedSuccessfully());
						Double newRate = ((location.getNumRates() * location.getRate()) + rating.getValue()) / (location.getNumRates()+1);
						location.setNumRates(location.getNumRates() + 1);
						location.setRate(newRate);
						rating.setReadOnly(true);
						String s3 = Info3K.msgs.views() + ": ";
						s3 += "<b>" + location.getViews() + "</b><br>"; 
						
						s3 += Info3K.msgs.rate() + ": ";
						String rate = location.getRate().toString();
						if(rate.length()>4) rate = rate.substring(0, 4);
						s3 += "<b>" + rate + "</b>";
						
						htmlViewRate.setHTML(s3);
					}
				});
			}
		});
	}

	public void execute() {
		center();
	}
}